package com.rightsidetech.user.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.rightsidetech.commom.dto.response.AdminHomeTopResp;
import com.rightsidetech.commom.utils.DateUtil;
import com.rightsidetech.user.dtos.requst.UserInfoReq;
import com.rightsidetech.user.dtos.response.*;
import com.rightsidetech.user.entity.*;
import com.rightsidetech.user.mapper.*;
import com.rightsidetech.user.service.UserInfoService;
import com.rightsidetech.commom.base.ResponseData;
import com.rightsidetech.commom.enums.CodeIdEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @Package: com.rightsidetech.trade.impl
 * @ClassName: UserInfoServiceImpl
 * @Author: yinj
 * @CreateTime: 2021/10/19 14:16
 */
@Slf4j
@Service("userInfoServiceImpl")
public class UserInfoServiceImpl implements UserInfoService {

    @Resource
    private UsUserInfoMapper usUserInfoMapper;
    @Resource
    private UsUserLoginInfoMapper usUserLoginInfoMapper;
    @Resource
    private UsUserLoginHistoryMapper usUserLoginHistoryMapper;
    @Resource
    private UsUserWechatInfoMapper usUserWechatInfoMapper;
    @Resource
    private UsUserAlipayInfoMapper usUserAlipayInfoMapper;
    @Resource
    private UsUserAccountInfoMapper usUserAccountInfoMapper;
    @Resource
    private UsUserAddressMapper usUserAddressMapper;
    @Resource
    private UsUserStatisMapper usUserStatisMapper;

    @Override
    public ResponseData<PageInfo<UserInfoResp>> listuser(UserInfoReq req) {
        PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<UserInfoResp> list = usUserInfoMapper.list(req);
        return ResponseData.success(new PageInfo<>(list));
    }

    @Override
    public ResponseData addBlacklist(Long userInfoId, Byte status) {
        UsUserInfo usUserInfo = usUserInfoMapper.selectByPrimaryKey(userInfoId);
        if (ObjectUtils.isEmpty(usUserInfo)) {
            return ResponseData.fail(CodeIdEnum.NOACCOUNT);
        }
        UsUserLoginInfo loginInfo = usUserLoginInfoMapper.selectByUserInfoId(userInfoId);
        if (ObjectUtils.isEmpty(loginInfo)) {
            return ResponseData.fail(CodeIdEnum.NOACCOUNT);
        }

        usUserLoginInfoMapper.addBlacklist(userInfoId, status);
        return ResponseData.success();
    }

    @Override
    public List<UserInfoResp> exportList(UserInfoReq userInfoReq) {
        return usUserInfoMapper.list(userInfoReq);
    }

    @Override
    public String getMaxMemberNo() {
        return usUserInfoMapper.getMaxMemberNo();
    }

    @Override
    public LoginResponse getLoginResponseByOpenId(String openid) {
        return usUserWechatInfoMapper.selectByOpenId(openid);
    }

    @Override
    public int updateTokenByLoginInfoId(Long loginInfoId, String token, String clientIp) throws Exception {

        UsUserLoginHistory userHistoryData = usUserLoginHistoryMapper.selectHistory(loginInfoId);
        if (!StringUtils.isEmpty(userHistoryData)) {
            UsUserLoginHistory usUserLoginHistory = new UsUserLoginHistory();
            usUserLoginHistory.setId(userHistoryData.getId());
            usUserLoginHistory.setLoginInfoId(loginInfoId);
            usUserLoginHistory.setOutTime(new Date());
            usUserLoginHistoryMapper.updateByPrimaryKeySelective(usUserLoginHistory);
        }

        Date date = new Date();
        SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat fm = new SimpleDateFormat("yyyy-MM-dd 02:00:00");
        UsUserLoginHistory userLoginHistory = new UsUserLoginHistory();
        userLoginHistory.setLoginInfoId(loginInfoId);
        userLoginHistory.setSource((byte) 3);
        userLoginHistory.setDeviceTag((byte) 3);
        userLoginHistory.setInTime(date);
        userLoginHistory.setValidTime(DateUtil.addDate(ft.parse(fm.format(date)), 14));
        userLoginHistory.setLoginIp(clientIp);
        usUserLoginHistoryMapper.insertSelective(userLoginHistory);

        return usUserLoginInfoMapper.updateTokenByLoginInfoId(loginInfoId, token);

    }

    @Override
    public LoginResponse checkOpenId(String openid, String clientIp) throws Exception {
        LoginResponse loginResponse = usUserWechatInfoMapper.selectByOpenId(openid);
        if (!ObjectUtils.isEmpty(loginResponse) && !StringUtils.isEmpty(loginResponse.getLoginInfoId())) {
            String token = UUID.randomUUID().toString().replace("-", "");
            updateTokenByLoginInfoId(loginResponse.getLoginInfoId(), token, clientIp);
            loginResponse.setToken(token);
            return loginResponse;
        }
        return null;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public LoginResponse registerUser(String phoneNumber, String openid, String maxMemberNo, String code, String type, String clientIp,
                                      Byte level, String levelName, String headImg, String petName) throws Exception {
        UsUserInfo userInfo = usUserInfoMapper.findByPhoneNo(phoneNumber);
        if (ObjectUtils.isEmpty(userInfo)) {
            userInfo = new UsUserInfo();
            userInfo.setMemberNo(maxMemberNo);
            userInfo.setMemberCode(code);
            userInfo.setPhoneNo(phoneNumber);
            userInfo.setHeadImg(headImg);
            userInfo.setPetName(petName);
            userInfo.setCreatedAt(new Date());
            usUserInfoMapper.insertSelective(userInfo);

            UsUserAccountInfo accountInfo = new UsUserAccountInfo();
            accountInfo.setUserInfoId(userInfo.getId());
            accountInfo.setCreatedAt(new Date());
            accountInfo.setLevel(level.longValue());
            accountInfo.setLevelName(levelName);
            usUserAccountInfoMapper.insertSelective(accountInfo);

        }
        UsUserLoginInfo usUserLoginInfo = usUserLoginInfoMapper.selectByLoginName(phoneNumber);
        if (ObjectUtils.isEmpty(usUserLoginInfo)) {
            usUserLoginInfo = new UsUserLoginInfo();
            usUserLoginInfo.setLoginName(phoneNumber);
            usUserLoginInfo.setUserInfoId(userInfo.getId());
            usUserLoginInfo.setToken(UUID.randomUUID().toString().replace("-", ""));
            usUserLoginInfo.setSalt(String.valueOf(Math.random() * 900000 + 100000));
            usUserLoginInfo.setPassword(DigestUtils.md5DigestAsHex(("pwd" + phoneNumber + usUserLoginInfo.getSalt()).getBytes()));
            usUserLoginInfoMapper.insertSelective(usUserLoginInfo);
        }

        updateTokenByLoginInfoId(usUserLoginInfo.getId(), usUserLoginInfo.getToken(), clientIp);

        LoginResponse loginResponse = new LoginResponse();
        if ("weChat".equals(type)) {
            UsUserWechatInfo wechatInfo = new UsUserWechatInfo();
            wechatInfo.setOpenid(openid);
            wechatInfo.setCreatedAt(new Date());
            wechatInfo.setUserInfoId(userInfo.getId());
            usUserWechatInfoMapper.insertSelective(wechatInfo);

        } else if ("aliPay".equals(type)) {
            UsUserAlipayInfo usUserUseridInfo = new UsUserAlipayInfo();
            usUserUseridInfo.setUserid(openid);
            usUserUseridInfo.setUserInfoId(userInfo.getId());
            usUserUseridInfo.setCreatedAt(new Date());
            usUserAlipayInfoMapper.insertSelective(usUserUseridInfo);
        }

        loginResponse.setLoginName(usUserLoginInfo.getLoginName());
        loginResponse.setRealName(userInfo.getRealName());
        loginResponse.setLoginInfoId(usUserLoginInfo.getId());
        loginResponse.setToken(usUserLoginInfo.getToken());

        return loginResponse;
    }

    @Override
    public ResponseData<UserInfoDetailsResp> findDetals(Long id) {
        UserInfoDetailsResp userInfoDetailsResp = usUserInfoMapper.findDetals(id);
        if (ObjectUtils.isEmpty(userInfoDetailsResp)){
            return ResponseData.fail(CodeIdEnum.EMPTY_DATA);
        }
        //查询地址
        List<UserAddressResp> addressRespList = usUserAddressMapper.findByUserInfoId(id);
        userInfoDetailsResp.setAdressList(addressRespList);
        return ResponseData.success(userInfoDetailsResp);
    }

    @Override
    public UsUserLoginInfo userCheckToken(String tokenApp) {
        UsUserLoginInfo loginInfo = usUserLoginInfoMapper.findByToken(tokenApp);
        if (StringUtils.isEmpty(loginInfo)) {
            log.info("未找到该用户");
            return null;
        }

        UsUserLoginHistory usUserLoginHistory = usUserLoginHistoryMapper.selectHistory(loginInfo.getId());
        if (StringUtils.isEmpty(usUserLoginHistory)) {
            log.info("未找到该用户");
            return null;
        }
        if (!StringUtils.isEmpty(usUserLoginHistory.getOutTime())) {
            log.info("该账户已登出");
            return null;
        } else if (new Date().after(usUserLoginHistory.getValidTime())) {
            log.info("该账户有效时间过期");
            return null;
        }
        return loginInfo;
    }

    @Override
    public UsUserWechatInfo findOpenid(String openid) {
        return usUserWechatInfoMapper.findOpenid(openid);
    }

    @Override
    public LoginInfoResp getLoginInfo(Long userInfoId) {
        LoginInfoResp loginInfoResp = usUserInfoMapper.getLoginInfo(userInfoId);
        if (ObjectUtils.isEmpty(loginInfoResp)){
            return null;
        }
        UserAddressResp addressResp = usUserAddressMapper.findDefaultByUserInfoId(userInfoId);
        if (!ObjectUtils.isEmpty(addressResp)){
            loginInfoResp.setAddressResp(addressResp);
        }
        return loginInfoResp;
    }

    @Override
    public LoginInfoResp getUserInfoByUserInfoId(Long userInfoId){
        return usUserInfoMapper.getLoginInfo(userInfoId);
    }

    @Override
    public String getHeadImg(Long userInfoId) {
        return usUserInfoMapper.getHeadImgByUserInfoId(userInfoId);
    }

    @Override
    public ResponseData logout(Long userInfoId) {
        UsUserLoginInfo loginInfo = usUserLoginInfoMapper.selectByUserInfoId(userInfoId);
        if (ObjectUtils.isEmpty(loginInfo)) {
            return ResponseData.fail(CodeIdEnum.NOACCOUNT);
        }
        usUserLoginInfoMapper.updateLoginOutTokenByLoginInfoId(loginInfo.getId(), null);
        UsUserLoginHistory userHistoryData = usUserLoginHistoryMapper.selectHistory(loginInfo.getId());
        if (!StringUtils.isEmpty(userHistoryData)) {
            UsUserLoginHistory usUserLoginHistory = new UsUserLoginHistory();
            usUserLoginHistory.setId(userHistoryData.getId());
            usUserLoginHistory.setLoginInfoId(loginInfo.getId());
            usUserLoginHistory.setOutTime(new Date());
            usUserLoginHistory.setValidTime(new Date());
            usUserLoginHistoryMapper.updateByPrimaryKeySelective(usUserLoginHistory);
        }
        return ResponseData.success();
    }

    @Override
    public ResponseData updateUsUserStatis(Long userInfoId, BigDecimal consumeAmount) {
        UsUserStatis usUserStatis = new UsUserStatis();
        usUserStatis.setUserInfoId(userInfoId);

        int count = 0;

        UsUserStatis usUserStatis1 = usUserStatisMapper.selectByUserInfoId(userInfoId);
        if (StringUtils.isEmpty(usUserStatis1)) {
            usUserStatis.setOrderNum(1L);
            usUserStatis.setConsumeAmount(consumeAmount);
            count = usUserStatisMapper.insertSelective(usUserStatis);
        } else {
            usUserStatis.setConsumeAmount(consumeAmount.add(usUserStatis1.getConsumeAmount()));
            usUserStatis.setOrderNum(usUserStatis1.getOrderNum() + 1L);
            count = usUserStatisMapper.updateByPrimaryKeySelective(usUserStatis);
        }

        return ResponseData.success();

    }

    @Override
    public void updateUserLevel(UsUserAccountInfo accountInfo) {
        usUserAccountInfoMapper.updateByUserInfoId(accountInfo);
    }

    @Override
    public UserAddressResp findAddressByUserInfoId(Long addressId , Long userInfoId) {
        return usUserAddressMapper.findByAddressIdAndUserInfoId(addressId, userInfoId);
    }

    @Override
    public String findForOpenId(Long userInfoId) {
        return usUserWechatInfoMapper.findForOpenId(userInfoId);
    }

    @Override
    public AdminHomeTopResp userStatis() {
        // 1代表昨日
        Long yesterdayUser = usUserInfoMapper.userStatis((byte)1);
        Long totalUser = usUserInfoMapper.userStatis(null);
        AdminHomeTopResp adminHomeTopResp = new AdminHomeTopResp();
        adminHomeTopResp.setYesterdayUser(yesterdayUser);
        adminHomeTopResp.setTotalUser(totalUser);
        return adminHomeTopResp;
    }

    @Override
    public UsLoginNameResp selectByPrimaryKey(Long id) {
        return usUserLoginInfoMapper.selectName(id);
    }

    @Override
    public Long selectByLoginId(Long loginId) {
        return usUserAccountInfoMapper.selectByLoginId(loginId);
    }

    @Override
    public UsUserInfo findByPhoneNo(String phoneNo) {
        return usUserInfoMapper.findByPhoneNo(phoneNo);
    }

    @Override
    public UsUserInfo registerImportOrder(String phoneNumber,String maxMemberNo,String code, Byte level,String levelName, String usName, UsUserAddress usUserAddress) {
        UsUserInfo userInfo = usUserInfoMapper.findByPhoneNo(phoneNumber);
        if (ObjectUtils.isEmpty(userInfo)) {
            userInfo = new UsUserInfo();
            userInfo.setMemberNo(maxMemberNo);
            userInfo.setMemberCode(code);
            userInfo.setPhoneNo(phoneNumber);
            userInfo.setCreatedAt(new Date());
            usUserInfoMapper.insertSelective(userInfo);

            UsUserAccountInfo accountInfo = new UsUserAccountInfo();
            accountInfo.setUserInfoId(userInfo.getId());
            accountInfo.setCreatedAt(new Date());
            accountInfo.setLevel(level.longValue());
            accountInfo.setLevelName(levelName);
            usUserAccountInfoMapper.insertSelective(accountInfo);

        }
        UsUserLoginInfo usUserLoginInfo = usUserLoginInfoMapper.selectByLoginName(phoneNumber);
        if (ObjectUtils.isEmpty(usUserLoginInfo)) {
            usUserLoginInfo = new UsUserLoginInfo();
            usUserLoginInfo.setLoginName(phoneNumber);
            usUserLoginInfo.setUserInfoId(userInfo.getId());
            usUserLoginInfo.setToken(UUID.randomUUID().toString().replace("-", ""));
            usUserLoginInfo.setSalt(String.valueOf(Math.random() * 900000 + 100000));
            usUserLoginInfo.setPassword(DigestUtils.md5DigestAsHex(("pwd" + phoneNumber + usUserLoginInfo.getSalt()).getBytes()));
            usUserLoginInfoMapper.insertSelective(usUserLoginInfo);
        }

        if(null != usUserAddress){
            usUserAddress.setUserInfoId(userInfo.getId());
            usUserAddress.setUserName(usName);
            usUserAddress.setUserPhone(phoneNumber);
            usUserAddress.setIsDefault((byte) 0);
            usUserAddress.setCreatedAt(new Date());
            usUserAddressMapper.insertSelective(usUserAddress);
        }

        return userInfo;
    }

    @Override
    public String findPhoneByNO(Long loginId) {
        return usUserLoginInfoMapper.findPhoneById(loginId);
    }

    @Override
    public LoginResponse getLoginResponseByUserId(String userId) {
        return usUserAlipayInfoMapper.getLoginResponseByUserId(userId);
    }

    @Override
    public UsUserLoginInfo selectById(Long id) {
        return usUserLoginInfoMapper.selectByUserInfoId(id);
    }
}
